<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>D20 Triangle Edge Control</title>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
padding: 20px;
background: #3f933f;
color: #d4e4f7;
min-height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
h1 {
margin-bottom: 50px;
font-size: 2.5em;
color: #c1ff31;
}
.triangle-wrapper {
position: relative;
width: 400px;
height: 400px;
margin: 0 auto;
}
.triangle-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 0;
height: 0;
border-left: 150px solid transparent;
border-right: 150px solid transparent;
border-bottom: 260px solid #d81159;
z-index: 1;
}
.edge-button {
position: absolute;
background: transparent;
border: none;
cursor: pointer;
transition: all 0.2s ease;
z-index: 10;
}
.edge-button::before {
content: '';
position: absolute;
font-size: 40px;
opacity: 0;
transition: opacity 0.2s ease;
color: #c1ff31;
}
.edge-button:hover::before {
opacity: 1;
}
.edge-button.active::before {
opacity: 1;
color: #ff6b35;
}
/* Left Edge */
.edge-left {
top: 50%;
left: 20%;
width: 120px;
height: 200px;
transform: translate(-50%, -50%) rotate(-30deg);
}
.edge-left::before {
content: '←';
top: 50%;
left: -20px;
transform: translateY(-50%) rotate(30deg);
}
.edge-left:hover {
filter: drop-shadow(0 0 10px #6a9bd4);
}
.edge-left.active {
filter: drop-shadow(0 0 15px #c1ff31);
}
/* Right Edge */
.edge-right {
top: 50%;
right: 20%;
width: 120px;
height: 200px;
transform: translate(50%, -50%) rotate(30deg);
}
.edge-right::before {
content: '→';
top: 50%;
right: -20px;
transform: translateY(-50%) rotate(-30deg);
}
.edge-right:hover {
filter: drop-shadow(0 0 10px #6a9bd4);
}
.edge-right.active {
filter: drop-shadow(0 0 15px #c1ff31);
}
/* Bottom Edge */
.edge-bottom {
bottom: 15%;
left: 50%;
width: 250px;
height: 60px;
transform: translateX(-50%);
}
.edge-bottom::before {
content: '↓';
bottom: -50px;
left: 50%;
transform: translateX(-50%);
}
.edge-bottom:hover {
filter: drop-shadow(0 0 10px #6a9bd4);
}
.edge-bottom.active {
filter: drop-shadow(0 0 15px #c1ff31);
}
/* Triangle glow effects */
.triangle-center.glow-left {
filter: drop-shadow(-10px 0 10px #6a9bd4);
}
.triangle-center.glow-right {
filter: drop-shadow(10px 0 10px #6a9bd4);
}
.triangle-center.glow-bottom {
filter: drop-shadow(0 10px 10px #6a9bd4);
}
.triangle-center.active-left {
border-bottom-color: #6a9bd4;
}
.triangle-center.active-right {
border-bottom-color: #6a9bd4;
}
.triangle-center.active-bottom {
border-bottom-color: #6a9bd4;
}
#status {
margin-top: 50px;
font-size: 18px;
color: #c1ff31;
font-weight: bold;
}
.label {
position: absolute;
font-size: 16px;
font-weight: bold;
color: #ffffff;
pointer-events: none;
}
.label-left {
top: 40%;
left: 15%;
}
.label-right {
top: 40%;
right: 15%;
}
.label-bottom {
bottom: 12%;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>
<body>
<h1>D20 Edge Control</h1>
<div class="triangle-wrapper">
<div class="triangle-center" id="triangleCenter"></div>
<button class="edge-button edge-left"
onmouseover="hoverEdge('left')"
onmouseout="clearHover()"
onclick="selectEdge(1, 'left')"></button>
<button class="edge-button edge-right"
onmouseover="hoverEdge('right')"
onmouseout="clearHover()"
onclick="selectEdge(2, 'right')"></button>
<button class="edge-button edge-bottom"
onmouseover="hoverEdge('bottom')"
onmouseout="clearHover()"
onclick="selectEdge(3, 'bottom')"></button>
<div class="label label-left">1</div>
<div class="label label-right">2</div>
<div class="label label-bottom">3</div>
</div>
<div id="status">Ready - Hover over triangle edges</div>
<script>
const status = document.getElementById('status');
const triangle = document.getElementById('triangleCenter');
function hoverEdge(edge) {
triangle.className = 'triangle-center glow-' + edge;
}
function clearHover() {
triangle.className = 'triangle-center';
// Keep active state if exists
const activeButton = document.querySelector('.edge-button.active');
if (activeButton) {
if (activeButton.classList.contains('edge-left')) {
triangle.className = 'triangle-center active-left';
} else if (activeButton.classList.contains('edge-right')) {
triangle.className = 'triangle-center active-right';
} else if (activeButton.classList.contains('edge-bottom')) {
triangle.className = 'triangle-center active-bottom';
}
}
}
function selectEdge(optionNumber, edge) {
// Remove active class from all buttons
document.querySelectorAll('.edge-button').forEach(b => b.classList.remove('active'));
// Add active class to clicked button
event.target.classList.add('active');
// Update triangle state
triangle.className = 'triangle-center active-' + edge;
// Update status
status.textContent = `Edge ${optionNumber} selected`;
// TODO: Send command to your actuator system here
// Example: fetch(`/edge?select=${optionNumber}`);
}
</script>
</body>
</html>